package com.linkallcloud.web.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.linkallcloud.core.lang.Lang;
import com.linkallcloud.core.log.Log;
import com.linkallcloud.core.log.Logs;

public abstract class LacCommonFilter implements Filter {
    protected static Log log = Logs.get();

    // 不过滤的uri
    protected List<String> notFilterResources = Lang.list("/static/", "/js/", "/css/", "/images/", "/img/", ".jpg",
            ".png", ".jpeg", ".js", ".css", "/login", "/imageValidate", "/verifyCode", "/exit", "/logout", "/nonce",
            "/nnl/", "/unsupport", "/error", "/pub/", "/ssoauth");

    // 需要过滤的uri
    protected List<String> filterResources = null;

    public LacCommonFilter() {
        super();
    }

    /**
     * @param ignoreRes
     * @param override
     *            是否覆盖
     */
    public LacCommonFilter(List<String> ignoreRes, boolean override) {
        this(ignoreRes, false, override);
    }

    /**
     * @param reses
     *            filterRes 和ignoreRes二选一，只能设置一个
     * @param isFilterRes
     *            是否filterRes
     * @param override
     *            是否覆盖
     */
    public LacCommonFilter(List<String> reses, boolean isFilterRes, boolean override) {
        if (isFilterRes) {
            this.initFilterResources(reses, override);
        } else {
            this.initNotFilterResources(reses, override);
        }
    }

    private void initFilterResources(List<String> reses, boolean override) {
        if (override) {
            this.filterResources = reses;
        } else if (reses != null && reses.size() > 0) {
            if (this.filterResources != null && this.filterResources.size() > 0) {
                for (String res : reses) {
                    boolean exist = false;
                    for (String uri : filterResources) {
                        if (uri.equals(res)) {
                            exist = true;
                            break;
                        }
                    }
                    if (!exist) {
                        this.filterResources.add(res);
                    }
                }
            } else {
                this.filterResources = new ArrayList<String>();
                for (String res : reses) {
                    this.filterResources.add(res);
                }
            }
        }
    }

    private void initNotFilterResources(List<String> reses, boolean override) {
        if (override) {
            this.notFilterResources = reses;
        } else if (reses != null && reses.size() > 0) {
            if (this.notFilterResources != null && this.notFilterResources.size() > 0) {
                for (String res : reses) {
                    boolean exist = false;
                    for (String uri : notFilterResources) {
                        if (uri.equals(res)) {
                            exist = true;
                            break;
                        }
                    }
                    if (!exist) {
                        this.notFilterResources.add(res);
                    }
                }
            } else {
                this.notFilterResources = new ArrayList<String>();
                for (String res : reses) {
                    this.notFilterResources.add(res);
                }
            }
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        doFilterInternal((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse, filterChain);
    }

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String uri = request.getRequestURI();
        if (needFiltered(uri)) {
            doConcreteFilter(request, response, filterChain);
        } else {
            filterChain.doFilter(request, response);
        }
    }

    protected abstract void doConcreteFilter(HttpServletRequest request, HttpServletResponse response,
            FilterChain filterChain) throws ServletException, IOException;

    /**
     * 是否需要过滤
     *
     * @param uri
     * @return
     */
    private boolean needFiltered(String uri) {
        if (this.filterResources != null && this.filterResources.size() > 0) {
            for (String s : this.filterResources) {
                if (uri.indexOf(s) != -1) {
                    return true;
                }
            }
            return false;
        } else {
            if (notFilterResources != null && notFilterResources.size() > 0) {
                for (String s : notFilterResources) {
                    if (uri.indexOf(s) != -1) {
                        return false;
                    }
                }
            }
            return true;
        }
    }

}
